package org.linlinjava.litemall.mechanismadmin.web;

import com.github.pagehelper.PageInfo;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.db.util.OrderHandleOption;
import org.linlinjava.litemall.db.util.OrderUtil;
import org.linlinjava.litemall.mechanismadmin.annotation.LoginAdmin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/mechanismadmin/order")
public class MechanismOrderController {
    @Autowired
    private LitemallOrderService orderService;

    @Autowired
    private LitemallOrderGoodsService orderGoodsService;

    @Autowired
    private LitemallMechanismUserService mechanismUserService;

    @Autowired
    private LitemallProductService productService;

    @Autowired
    private PlatformTransactionManager txManager;

    @Autowired
    private LitemallWalletRecordService walletRecordService;

    @GetMapping("/list")
    public Object list(
            @LoginAdmin Integer adminId,
            Short value,
            String orderSn,
            String addTime,
            @RequestParam(required = false) List<Short> orderStatusArray,
            @RequestParam(value = "page", defaultValue = "1") Integer page,
            @RequestParam(value = "limit", defaultValue = "10") Integer limit,
            String sort,
            String order) {
        if (adminId == null) {
            return ResponseUtil.unlogin();
        }
        LocalDateTime start = null;
        LocalDateTime end = null;
        if(addTime != null && !"".equals(addTime)){
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            start = LocalDateTime.parse(addTime.split(",")[0],df);
            end = LocalDateTime.parse(addTime.split(",")[1],df);
        }
        List<LitemallOrder> orderList = orderService.querySelectives(adminId, orderSn, value, start, end, orderStatusArray, page, limit, sort, order);
        long total = PageInfo.of(orderList).getTotal();
        Map<String, Object> data = new HashMap<>();
        data.put("total", total);
        data.put("items", orderList);

        return ResponseUtil.ok(data);
    }

    @GetMapping("/totalList")
    public Object totalList(
            @LoginAdmin Integer adminId,
            Short value,
            String orderSn,
            String addTime,
            @RequestParam(required = false, value = "orderStatusArray[]") List<Short> orderStatusArray,
            String sort,
            String order) {

        LocalDateTime start = null;
        LocalDateTime end = null;
        if(addTime != null && !"".equals(addTime)){
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            start = LocalDateTime.parse(addTime.split(",")[0],df);
            end = LocalDateTime.parse(addTime.split(",")[1],df);
        }
        List<LitemallOrder> orderList = orderService.queryTotalSelectives(adminId, orderSn, value, start, end, orderStatusArray, sort, order);

        Map<String, Object> data = new HashMap<>(1);
        data.put("items", orderList);

        return ResponseUtil.ok(data);
    }

    @GetMapping("/detail")
    public Object detail(@LoginAdmin Integer adminId, @NotNull Integer id) {
        if (adminId == null) {
            return ResponseUtil.unlogin();
        }

        LitemallOrder order = orderService.findById(id);
        List<LitemallOrderGoods> orderGoods = orderGoodsService.queryByOid(id);

        LitemallMechanismUser mechanismUser = null;

        mechanismUser = mechanismUserService.findById(order.getUserId());

        Map<String, Object> data = new HashMap<>();
        data.put("order", order);
        data.put("orderGoods", orderGoods);
        data.put("mechanismUser", mechanismUser);

        return ResponseUtil.ok(data);
    }

    /**
     * 取消订单
     * @param adminId 用户ID
     * @param id 订单ID
     */
    @GetMapping("/cancal")
    public Object cancal(@LoginAdmin Integer adminId, @NotNull Integer id) {
        if (adminId == null) {
            return ResponseUtil.unlogin();
        }
        if (id == null) {
            return ResponseUtil.badArgument();
        }

        LitemallOrder order = orderService.findById(id);
        if (order == null) {
            return ResponseUtil.badArgumentValue();
        }
        if (!order.getUserId().equals(adminId)) {
            return ResponseUtil.badArgumentValue();
        }

        // 检测是否能够取消
        OrderHandleOption handleOption = OrderUtil.build(order);
        if (!handleOption.isCancel()) {
            return ResponseUtil.fail(403, "订单不能取消");
        }

        // 开启事务管理
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = txManager.getTransaction(def);
        try {
            // 设置订单已取消状态
            order.setOrderStatus(OrderUtil.STATUS_CANCEL);
            order.setEndTime(LocalDateTime.now());
            orderService.update(order);

            // 商品货品数量增加
            List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(id);
            for (LitemallOrderGoods orderGoods : orderGoodsList) {
                Integer productId = orderGoods.getProductId();
                LitemallProduct product = productService.findById(productId);
                Integer number = product.getNumber() + orderGoods.getNumber();
                product.setNumber(number);
                productService.updateById(product);
            }
        }
        catch (Exception ex) {
            txManager.rollback(status);
            return ResponseUtil.fail(403, "订单取消失败");
        }
        txManager.commit(status);

        return ResponseUtil.ok();
    }

    @GetMapping("/ordersList")
    public Object ordersList(@LoginAdmin Integer adminId, @NotNull Integer id) {
        LitemallOrder litemallOrder = orderService.findById(id);
        LitemallOrderGoods litemallOrderGoods = orderGoodsService.queryByOid(id).get(0);

        Map<String, Object> data = new HashMap<>();
        data.put("order", litemallOrder);
        data.put("orderGoods", litemallOrderGoods);

        return ResponseUtil.ok(data);
    }

    @GetMapping("/modifyOrder")
    public Object modifyOrder(@LoginAdmin Integer adminId, String beforeOrderSn, String orderSn, String orderId){
        if(!"".equals(beforeOrderSn)){
            LitemallWalletRecord litemallWalletRecord = walletRecordService.queryByRecordSn(beforeOrderSn);
            litemallWalletRecord.setRecordSn(orderSn);
            walletRecordService.update(litemallWalletRecord);
        }

        if(!"".equals(orderId)){
            LitemallOrder litemallOrder = orderService.findById(Integer.parseInt(orderId));
            litemallOrder.setOrderSn(orderSn);
            orderService.update(litemallOrder);
        }
        return ResponseUtil.ok();
    }
}